﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace LSI_interface
{
	class Compute
	{
		public int docNum, termNum;
		public double[] TFM;
		public double appError;
		public int pseudoTermNum;
		public int[] Groups;

		List<string>[] retrievedDB;
		List<string> terms;

		DBconnect DB;

		public Compute()
		{
			DB = new DBconnect();
            docNum = DB.Count("n_norm");
            termNum = DB.Count("s_deskryptory");
			retrievedDB = new List<string>[3];
			terms = new List<string>();
			Groups = new int[docNum];
			TFM = new double[docNum * termNum];
			InitMatrixByVal(TFM, 0);
			appError = 0.0001;
			pseudoTermNum = 100;
		}

        public void RetrieveDB()
        {
            retrievedDB = DB.SelectAllFrom_norm();
            terms = DB.SelectAllFrom_desk();
        }

		public void createTFM()
		{			
			int iter = 0;
			for (int i = 0; i < docNum; i++)
			{
				for (int j = 0; j < termNum; j++)
				{
					//TFM[i, j] += countTerm(retrievedDB[1][i], terms[j]);
					//TFM[i, j] += countTerm(retrievedDB[2][i], terms[j]);
					TFM[iter] += countTerm(retrievedDB[1][i], terms[j]);
					TFM[iter++] += countTerm(retrievedDB[2][i], terms[j]);
				}
			}
		}

		private int countTerm(string text, string searchTerm)
		{
			/*
			 * http://msdn.microsoft.com/en-us/library/bb546166.aspx
			 */

			//Convert the string into an array of words 
			string[] source = text.Split(new char[] { '.', '?', '!', ' ', ';', ':', ',' }, StringSplitOptions.RemoveEmptyEntries);

			// Create and execute the query. It executes immediately  
			// because a singleton value is produced. 
			// Use ToLowerInvariant to match "data" and "Data"  
			var matchQuery = from word in source
							 where word.ToLowerInvariant() == searchTerm.ToLowerInvariant()
							 select word;

			// Count the matches. 
			int wordCount = matchQuery.Count();

			return wordCount;
		}

		private void InitMatrixByVal(double[] matrix, int var)
		{
			//
			// Initialize array with for loop
			//
			for (int i = 0; i < matrix.Length; i++)
					matrix[i] = var;
		}

		[DllImport("C:\\Users\\paweln66\\Documents\\Study\\AGH\\IMiIP\\II degree\\I semester\\Data mining\\Project\\LatentSemanticIndexingENGINE\\Release\\InterfaceDLL.dll", CallingConvention = CallingConvention.Cdecl)]
		private static extern double computeSVD(double[] pTFM, int dNum, int tNum, ref double approxiError, int[] pGroups, ref int pPseudoTermNum);

		public void ComputeSVD()
		{
			computeSVD(TFM, docNum, termNum, ref appError, Groups, ref pseudoTermNum);
		}

		public void ComputeSVD_TEST()
		{
			int m = 10;
			int n = 6;

			double[] M = new double[] { 24, 21, 9, 0, 0, 3,
				32, 10, 5, 0, 3, 0,
				12, 16, 5, 0, 0, 0,
				6, 7, 2, 0, 0, 0,
				43, 31, 20, 0, 3, 0, 
				2, 0, 0, 18, 7, 16, 
				0, 0, 1, 32, 12, 0, 
				3, 0, 0, 22, 4, 2, 
				1, 0, 0, 34, 27, 25,
				6, 0, 0, 17, 4, 23 };


			double appError = 0.08;
			int pseudoTermNum = 0;
			int[] Groups = new int[m];

			computeSVD(M, m, n, ref appError, Groups, ref pseudoTermNum);
		}

        public List<string> RetrieveGroup(int numGrp)
        {
            List<string> titles = new List<string>();

            for (int i = 0; i < docNum; i++)
            {
                if (numGrp == Groups[i])
                {
                    titles.Add(retrievedDB[1][i]);
                }
            }

            return titles;
        }
	}
}
